<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
window.jsTestIsAsync = true;
description("Tests that properties passed to events are not garbage collected prematurely.");

function addListener(eventType, prop) {
    document.addEventListener(eventType, function(event) {
        window.prop = prop;
        // Despite the earlier assignement of the local variable to null and
        // the following garabage collection, the property should still be
        // present here.
        shouldBeEqualToString("event[prop]", "foo");

        window.prop = undefined;
        window.postMessage("done", "*");
    });
}

// Run the tests whenever a notification arrives, which indicates that the
// previous test has finished.
window.addEventListener("message", function(message) {
    runNextTest();
}, false);

function newEvent(eventType, prop, value) {
    return eval("new " + eventType + "('" + eventType + "', { " + prop + ": value })");
}

// The events that we want to test, with the properties that each one uses.
var events = [
    { eventType: "CustomEvent", prop: "detail" },
    { eventType: "MessageEvent", prop: "data" },
    { eventType: "PopStateEvent", prop: "state" }
];

function runNextTest () {
    var evt = events.pop();
    if (!evt) {
        finishJSTest();
        return;
    }

    var value = "foo";
    var eventToDispatch = newEvent(evt.eventType, evt.prop, value);
    value = null;
    gc();

    addListener(evt.eventType, evt.prop);
    document.dispatchEvent(eventToDispatch);
};

// This test is meaningless without testRunner.
if (window.testRunner) {
    runNextTest();
}
</script>
</body>
</html>
